Android类似微信聊天的页面开发教程(Kotlin)三

您所在的位置:网站首页 android studio微信聊天界面代码 Android类似微信聊天的页面开发教程(Kotlin)三

Android类似微信聊天的页面开发教程(Kotlin)三

2024-07-01 18:32| 来源: 网络整理| 查看: 265

 

前提条件

安装并配置好Android Studio

Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built on February 17, 2023 Runtime version: 11.0.15+0-b2043.56-9505619 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 1280M Cores: 6 Registry:     external.system.auto.import.disabled=true     ide.text.editor.with.preview.show.floating.toolbar=false     ide.balloon.shadow.size=0   Non-Bundled Plugins:     com.intuit.intellij.makefile (1.0.15)     com.github.setial (4.0.2)     com.alayouni.ansiHighlight (1.2.4)     GsonOrXmlFormat (2.0)     GLSL (1.19)     com.mistamek.drawablepreview.drawable-preview (1.1.5)     com.layernet.plugin.adbwifi (1.0.5)     com.likfe.ideaplugin.eventbus3 (2020.0.2)

gradle-wrapper.properties

#Tue Apr 25 13:34:44 CST 2023 distributionBase=GRADLE_USER_HOME distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME

build.gradle(:Project)

// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins {     id 'com.android.application' version '7.3.1' apply false     id 'com.android.library' version '7.3.1' apply false     id 'org.jetbrains.kotlin.android' version '1.7.20' apply false }

setting.gradle

pluginManagement {     repositories {         google()         mavenCentral()         gradlePluginPortal()         maven { url 'https://jitpack.io' }     } } dependencyResolutionManagement {     repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)     repositories {         google()         mavenCentral()         gradlePluginPortal()         maven { url 'https://jitpack.io' }     } } rootProject.name = "logindemo" include ':app'

build.gralde(:app)

plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } android { namespace 'com.example.fechat' compileSdk 33 defaultConfig { applicationId "com.example.fechat" minSdk 26 targetSdk 33 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { jvmTarget = '1.8' } } dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' // 沉浸式状态栏 https://github.com/gyf-dev/ImmersionBar implementation 'com.gyf.immersionbar:immersionbar:3.0.0' implementation 'com.gyf.immersionbar:immersionbar-components:3.0.0' // fragment快速实现(可选) implementation 'com.gyf.immersionbar:immersionbar-ktx:3.0.0' // kotlin扩展(可选) implementation 'com.google.code.gson:gson:2.8.9' }

对Kotlin语言有基本了解

内容在前一篇博客中写了基础配置,如果本篇内容看不懂,可以先去上一篇。

增加聊天页面 activity_message.xml中 标题+内容RecyclerView+底部输入框+发送 package com.example.fechat.activity import android.annotation.SuppressLint import android.os.Bundle import android.widget.EditText import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.fechat.R import com.example.fechat.adapter.ChatAdapter import com.example.fechat.bean.ChatBean import com.example.fechat.bean.MessageBean import com.google.gson.Gson import com.gyf.immersionbar.ImmersionBar class MessageActivity : AppCompatActivity() { private val beans: MutableList = ArrayList() private var adapter: ChatAdapter? = null private lateinit var itemView: RecyclerView private lateinit var chatBean: ChatBean override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ImmersionBar.with(this) .statusBarDarkFont(true) .statusBarColor(R.color.title) .navigationBarColor(R.color.white) .navigationBarDarkIcon(true) .init() setContentView(R.layout.activity_message) val backTv = findViewById(R.id.backTv) val inputText: EditText = findViewById(R.id.inputText) val sendText: TextView = findViewById(R.id.sendText) val userName: TextView = findViewById(R.id.userName) backTv.setOnClickListener { finish() } sendText.setOnClickListener { sendText(inputText.text.toString()) } initItemRecyclerView() getBundle() userName.text = chatBean.nick } private fun getBundle() { val userInfo = intent.getStringExtra("UserInfo") chatBean = Gson().fromJson(userInfo, ChatBean::class.java) } private fun initItemRecyclerView() { itemView = findViewById(R.id.itemView) val layoutManager = LinearLayoutManager(this) layoutManager.orientation = RecyclerView.VERTICAL itemView.layoutManager = layoutManager adapter = ChatAdapter(beans) itemView.adapter = adapter } @SuppressLint("NotifyDataSetChanged") private fun sendText(message: String) { beans.add( MessageBean( message, "用户", false, System.currentTimeMillis() ) ) beans.add( MessageBean( message, chatBean.nick, true, System.currentTimeMillis(), true ) ) adapter?.notifyDataSetChanged() } } 制作聊天适配器

适配器的xml中,分为两部分 主用户发送消息,同时接收聊天对象的消息

package com.example.fechat.adapter import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.Adapter import com.example.fechat.R import com.example.fechat.bean.MessageBean import com.example.fechat.view.CircleImageView import java.text.SimpleDateFormat import java.util.* class ChatAdapter(private val data: List) : Adapter() { private fun getTime(time: Long): String { val sDateFormat = SimpleDateFormat("MM-dd HH:mm", Locale.getDefault()) return sDateFormat.format(time) } class BaseHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val userLayout: RelativeLayout = itemView.findViewById(R.id.userLayout) val userHead: CircleImageView = itemView.findViewById(R.id.userHead) val userMessage: TextView = itemView.findViewById(R.id.userMessage) val userTime: TextView = itemView.findViewById(R.id.userTime) val respLayout: RelativeLayout = itemView.findViewById(R.id.respLayout) val respHead: CircleImageView = itemView.findViewById(R.id.respHead) val respMessage: TextView = itemView.findViewById(R.id.respMessage) val respTime: TextView = itemView.findViewById(R.id.respTime) val respImage: ImageView = itemView.findViewById(R.id.respImage) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_message, null, false); return BaseHolder(view) } override fun getItemCount(): Int { return data.size } override fun onBindViewHolder(holder: BaseHolder, position: Int) { val item = data[position] if (item.isResponse) { holder.respLayout.visibility = View.VISIBLE holder.userLayout.visibility = View.GONE holder.respMessage.text = item.message holder.respTime.text = getTime(item.time) } else { holder.userLayout.visibility = View.VISIBLE holder.respLayout.visibility = View.GONE holder.userMessage.text = item.message holder.userTime.text = getTime(item.time) } } }

聊天内容适配器中的data数据结构如下:

package com.example.fechat.bean data class MessageBean( var message: String, var userName: String, var isResponse: Boolean = false, var time: Long, var isSuccess: Boolean = true )

其中首页用户聊天列表中的data修改,主要是data转化为string方便intent传输,如下:

package com.example.fechat.bean data class ChatBean( val head: String, val nick: String, val newest: String, val date: String ) { override fun toString(): String { return "{head:$head,nick:$nick,newest:$newest,date:$date}" } }

首页用户聊天记录的适配器作如下修改,主要是增加了适配器点击事件监听器:

package com.example.fechat.base import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.example.fechat.R import com.example.fechat.bean.ChatBean class BaseAdapter(private val data: List) : RecyclerView.Adapter() { private lateinit var onItemClickListener: OnItemClickListener override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.base_item, null, false); return BaseHolder(view) } override fun getItemCount(): Int { return data.size } override fun onBindViewHolder(holder: BaseHolder, position: Int) { holder.headTv.visibility = if (data[position].head.isEmpty()) View.GONE else View.VISIBLE holder.nickTv.visibility = if (data[position].nick.isEmpty()) View.GONE else View.VISIBLE holder.newestTv.visibility = if (data[position].newest.isEmpty()) View.GONE else View.VISIBLE holder.dateTv.visibility = if (data[position].date.isEmpty()) View.GONE else View.VISIBLE holder.headTv.text = data[position].head holder.nickTv.text = data[position].nick holder.newestTv.text = data[position].newest holder.dateTv.text = data[position].date holder.itemView.setOnClickListener { onItemClickListener.onItemClick(holder.itemView, position) } } class BaseHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val headTv: TextView = itemView.findViewById(R.id.headTv) val nickTv: TextView = itemView.findViewById(R.id.nickTv) val newestTv: TextView = itemView.findViewById(R.id.newestTv) val dateTv: TextView = itemView.findViewById(R.id.dateTv) } fun setOnItemClickListener(onItemClickListener: OnItemClickListener) { this.onItemClickListener = onItemClickListener } interface OnItemClickListener { fun onItemClick(view: View, position: Int) } } 点击跳转到聊天页面 package com.example.fechat.fragment import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.fechat.R import com.example.fechat.activity.MessageActivity import com.example.fechat.base.BaseAdapter import com.example.fechat.bean.ChatBean class ChatFragment : Fragment() { private lateinit var recyclerView: RecyclerView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_chat, container, false) recyclerView = view.findViewById(R.id.recyclerView) val data = ArrayList() data.add(ChatBean("头像0", "用户0", "聊天记录0", "4月25日")) data.add(ChatBean("头像1", "用户1", "聊天记录1", "4月24日")) data.add(ChatBean("头像2", "用户2", "聊天记录2", "4月23日")) data.add(ChatBean("头像3", "用户3", "聊天记录3", "4月22日")) data.add(ChatBean("头像4", "用户4", "聊天记录4", "4月21日")) data.add(ChatBean("头像5", "用户5", "聊天记录5", "4月20日")) data.add(ChatBean("头像6", "用户6", "聊天记录6", "4月19日")) data.add(ChatBean("头像7", "用户7", "聊天记录7", "4月18日")) data.add(ChatBean("头像8", "用户8", "聊天记录8", "4月17日")) data.add(ChatBean("头像9", "用户9", "聊天记录9", "4月16日")) recyclerView.layoutManager = LinearLayoutManager(context) val baseAdapter = BaseAdapter(data) recyclerView.adapter = baseAdapter baseAdapter.setOnItemClickListener(object : BaseAdapter.OnItemClickListener { override fun onItemClick(view: View, position: Int) { val intent = Intent(context, MessageActivity::class.java) intent.putExtra("UserInfo", data[position].toString()) startActivity(intent) } }) return view } } 开源地址

FeChat: 模仿微信



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3